home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 1.iso / ARGONET / PD / GRAPHICS / GIF2RPC.SPK / source / 16bpp_66bit / c / fsi < prev    next >
Text File  |  1995-10-16  |  4KB  |  122 lines

  1. /* fsi.c
  2.  * AUTHOR:      Cy Booker, cy@cheepnis.demon.co.uk
  3.  * LICENSE:     FreeWare, Copyright (c) 1995 Cy Booker
  4.  *
  5.  * filter:              *  7
  6.  *                   3  5  1            (1/16)
  7.  */
  8.  
  9. #include "internal.h"
  10.  
  11. #include <assert.h>
  12. #include <string.h>             /* memset() */
  13. #include <stdlib.h>             /* calloc() */
  14.  
  15. #include "OS:hourglass.h"
  16. #include "OS:macros.h"
  17.  
  18.  
  19.  
  20. /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  21.  */
  22.  
  23. extern bool process_gif_16bpp_floyd_steinberg_66bit(
  24.                 const process_gif       *p) {
  25.   byte                  *rove;
  26.   int                   width, height;
  27.   int                   x, y;
  28.   const os_colour       *palette;
  29.   int                   line_length;
  30.   int                   *buffer, *this_row, *next_row;
  31.   int                   buffer_width;
  32.   int                   r, g, b;
  33.   int                   or, og, ob;
  34.   int                   t;
  35.   int                   er, eg, eb;
  36.   int                   eblr, eblg, eblb;
  37.   int                   ebr, ebg, ebb;
  38.  
  39.   assert(p);
  40.   assert(p->pixel_width > 0);
  41.   assert(p->pixel_height > 0);
  42.   assert(p->in_palette.colours);
  43.  
  44.   /*
  45.    * floyd_steinberg requires storing error info for one pixel to right and one pixel to left
  46.    * so we will just allocate an extra column for each row and not do any edge checks
  47.    * each entry is stored as {r*SCALE, g*SCALE, b*SCALE}
  48.    */
  49.   buffer_width = (p->pixel_width + 2) * 3;
  50.   buffer = calloc(1, sizeof(*buffer) * (buffer_width * 2));
  51.   if (!buffer) {
  52.     /*
  53.      * oh dear
  54.      */
  55.     return TRUE;
  56.   }
  57.  
  58.   initialise_scaling_tables();
  59.  
  60.   /*
  61.    * not we pre-load values from the process_gif array
  62.    * because it considerably helps the compiler produce better code
  63.    */
  64.   rove = p->buffer;
  65.   width = p->pixel_width;
  66.   height = p->pixel_height;
  67.   palette = p->in_palette.colours;
  68.   line_length = p->line_length;
  69.   for (y= height; (y > 0); y--) {
  70.     if ((y & 7) == 0) {
  71.       xhourglass_percentage((y * 100) / height);
  72.     }
  73.     this_row = buffer + (buffer_width * ((y + 2) % 2)) + 1*3;        /* skip left hand 'dummy' column */
  74.     next_row = buffer + (buffer_width * ((y + 1) % 2));   /* point inside left hand dummy column */
  75.     memset(next_row, 0, sizeof(*next_row) * buffer_width);/* next row has no errors */
  76.     er = eg = eb = 0;                                   /* error along this row */
  77.     /*
  78.      * note that just because we are actually scanning/outputting right to left
  79.      * doesn't matter as far as floyd_steinberg is concerned
  80.      * although it might help if we could ``snake''
  81.      */
  82.     for (x= width - 1; (x >= 0); x--) {
  83.       INPUT;
  84.       r += *this_row++;                                 /* add in errors from other row */
  85.       r += er;                                          /* add in errors from this row */
  86.       g += *this_row++;
  87.       g += eg;
  88.       b += *this_row++;
  89.       b += eb;
  90.       PROCESS;
  91.       r -= or;                                          /* error */
  92.       g -= og;
  93.       b -= ob;
  94.       er = (r * 7) / 16;                                /* diffuse pixel to `right' */
  95.       eg = (g * 7) / 16;
  96.       eb = (b * 7) / 16;
  97.       eblr = (r * 3) / 16;                              /* diffuse pixel `below left' */
  98.       eblg = (g * 3) / 16;
  99.       eblb = (b * 3) / 16;
  100.       *next_row += eblr; next_row++;
  101.       *next_row += eblg; next_row++;
  102.       *next_row += eblb; next_row++;
  103.       ebr = (r * 5) / 16;                               /* diffuse pixel `below' */
  104.       ebg = (g * 5) / 16;
  105.       ebb = (b * 5) / 16;
  106.       *next_row += ebr; next_row++;
  107.       *next_row += ebg; next_row++;
  108.       *next_row += ebb; next_row++;
  109.       *next_row += r - (er + eblr + ebr); next_row++;  /* diffuse pixel `below right' */
  110.       *next_row += g - (eg + eblg + ebg); next_row++;
  111.       *next_row += b - (eb + eblb + ebb); next_row++;
  112.       next_row -= 3*2;                                  /* adjust next_row pointer */
  113.     }
  114.     rove += line_length;
  115.   }
  116.   free(buffer);
  117.   return FALSE;
  118. }
  119.  
  120.  
  121.  
  122.